package tech.runchen.gz5055.oms.modules.system.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import tech.runchen.gz5055.oms.common.annotation.RequiresPermissions;
import tech.runchen.gz5055.oms.common.annotation.SysLog;
import tech.runchen.gz5055.oms.common.base.AbstractController;
import tech.runchen.gz5055.oms.common.enums.BusinessType;
import tech.runchen.gz5055.oms.common.enums.OrderStatus;
import tech.runchen.gz5055.oms.common.enums.UserType;
import tech.runchen.gz5055.oms.common.utils.PageInfo;
import tech.runchen.gz5055.oms.common.utils.Result;
import tech.runchen.gz5055.oms.common.utils.redis.delay.RedisDelayQueueManager;
import tech.runchen.gz5055.oms.common.utils.redis.delay.OrderTimeoutDoneTask;
import tech.runchen.gz5055.oms.common.utils.redis.delay.OrderTimeoutShippedTask;
import tech.runchen.gz5055.oms.modules.system.entity.BarcodeEntity;
import tech.runchen.gz5055.oms.modules.system.entity.OrderDetailEntity;
import tech.runchen.gz5055.oms.modules.system.entity.OrderEntity;
import tech.runchen.gz5055.oms.modules.system.form.OrderReceiptForm;
import tech.runchen.gz5055.oms.modules.system.form.OrderShipmentForm;
import tech.runchen.gz5055.oms.modules.system.service.IBarcodeService;
import tech.runchen.gz5055.oms.modules.system.service.INoticeService;
import tech.runchen.gz5055.oms.modules.system.service.IOrderDetailService;
import tech.runchen.gz5055.oms.modules.system.service.IOrderService;

import java.util.Map;

/**
 * <p>
 * 订单信息表 前端控制器
 * </p>
 *
 * @author zzj
 * @since 2023-10-10
 */
@Api(tags = "管理平台 - 订单管理")
@RestController
@RequestMapping("/sys/order")
public class SysOrderController extends AbstractController {

    @Autowired
    private IOrderService orderService;
    @Autowired
    private IOrderDetailService orderDetailService;
    @Autowired
    private IBarcodeService barcodeService;
    @Autowired
    private INoticeService noticeService;
    @Autowired
    private RedisDelayQueueManager redisDelayQueueManager;

    @ApiOperation("订单信息")
    @RequiresPermissions(value = {UserType.SPD, UserType.NURSE})
    @GetMapping("/list")
    public Result list(@RequestParam Map<String, Object> params) {
        params.put("userType", getLoginUser().getUser().getType());
        params.put("userId", getUserId());
        PageInfo page = orderService.queryPage(params);
        return Result.success(page);
    }

    @ApiOperation("待发货订单信息(机器人存货)")
    @RequiresPermissions(value = {UserType.SPD})
    @GetMapping("/unshipped")
    public Result unshipped(@RequestParam Map<String, Object> params) {
        params.put("userType", getLoginUser().getUser().getType());
        params.put("userId", getUserId());
        PageInfo page = orderService.queryUnshippedOrder(params);
        return Result.success(page);
    }

    @ApiOperation("待收货订单信息(机器人取货)")
    @RequiresPermissions(value = {UserType.NURSE})
    @GetMapping("/unreceived")
    public Result unreceived(@RequestParam Map<String, Object> params) {
        params.put("userType", getLoginUser().getUser().getType());
        params.put("userId", getUserId());
        PageInfo page = orderService.queryUnreceivedOrder(params);
        return Result.success(page);
    }

    @ApiOperation("订单详情")
    @RequiresPermissions(value = {UserType.SPD, UserType.NURSE})
    @GetMapping("/{orderId}")
    public Result info(@PathVariable("orderId") Long orderId) {
        OrderEntity order = orderService.getById(orderId);
        order.setOrderDetailList(orderDetailService.list(new QueryWrapper<OrderDetailEntity>().eq("order_id", orderId)));
        return Result.success(order);
    }

    @SysLog(title = "创建订单", businessType = BusinessType.INSERT)
    @ApiOperation("创建订单")
    @RequiresPermissions(value = {UserType.SPD, UserType.NURSE})
    @PostMapping("/create")
    public Result create(@Validated @RequestBody OrderEntity order) {
        order.setOrderTime(System.currentTimeMillis());
        order.setOrderUserId(getUserId());
        order.setOrderUserName(getNickName());
        if (getLoginUser().getUser().getType().equals(UserType.SPD.getCode())) {
            order.setOrderType(1);
            order.setStatus(1);
        }
        orderService.saveOrder(order);
        // 创建即时消息
        noticeService.createOrderNotice(order, OrderStatus.WAIT);
        // 设置发货超时提醒
        redisDelayQueueManager.addTask(new OrderTimeoutShippedTask(OrderTimeoutShippedTask.TAG + order.getId(), order.getId().toString(), OrderTimeoutShippedTask.TIMEOUT));
        return Result.success();
    }

    @SysLog(title = "确认订单", businessType = BusinessType.OPERATE)
    @ApiOperation("确认订单")
    @RequiresPermissions(value = {UserType.SPD})
    @PutMapping("/confirm/{orderId}")
    public Result confirm(@PathVariable("orderId") long orderId) {
        OrderEntity order = orderService.getById(orderId);
        if (order.getStatus() != OrderStatus.WAIT.getValue()) {
            return Result.error("订单状态异常，请刷新后重试");
        }
        //订单确认状态及确认人
        order.setStatus(1);
        order.setConfirmOrderTime(System.currentTimeMillis());
        order.setConfirmOrderUserId(getUserId());
        order.setConfirmOrderUserName(getNickName());
        orderService.updateOrder(order);
        return Result.success();
    }

    @SysLog(title = "订单发货", businessType = BusinessType.OPERATE)
    @ApiOperation("订单发货")
    @RequiresPermissions(value = {UserType.SPD})
    @PutMapping("/shipment")
    public Result shipment(@Validated @RequestBody OrderShipmentForm orderShipment) {
        OrderEntity order = orderService.getById(orderShipment.getOrderId());
        if (order.getStatus() != OrderStatus.WAIT.getValue() && order.getStatus() != OrderStatus.CONFIRM.getValue()) {
            return Result.error("订单状态异常，请刷新后重试");
        }
        //如果订单未确认直接发货则补全订单的确认人
        if (order.getConfirmOrderUserId() == null || order.getConfirmOrderTime() == null) {
            order.setConfirmOrderTime(System.currentTimeMillis());
            order.setConfirmOrderUserId(getUserId());
            order.setConfirmOrderUserName(getNickName());
        }
        //订单发货状态及发货人补全
        order.setStatus(2);
        order.setShippedTime(System.currentTimeMillis());
        order.setShippedUserId(getUserId());
        order.setShippedUserName(getNickName());
        //设置配送方式和配送人
        order.setDeliveryMethod(orderShipment.getDeliveryMethod());
        order.setDeliveryBy(orderShipment.getDeliveryBy());
        orderService.updateOrder(order);
        // 如果是人工配送则直接调用订单完成接口
        if (orderShipment.getDeliveryMethod() == 1) {
            OrderReceiptForm orderReceiptForm = new OrderReceiptForm();
            orderReceiptForm.setOrderId(orderShipment.getOrderId());
            orderReceiptForm.setBarcodeList(orderShipment.getBarcodeList());
            return receipt(orderReceiptForm);
        } else {
            // 创建即时消息
            noticeService.createOrderNotice(order, OrderStatus.SHIPPED);
            // 移除发货超时提醒
            redisDelayQueueManager.removeTask(OrderTimeoutDoneTask.TAG + order.getId());
            // 设置配送超时提醒
            redisDelayQueueManager.addTask(new OrderTimeoutDoneTask(OrderTimeoutDoneTask.TAG + order.getId(), order.getId().toString(), OrderTimeoutDoneTask.TIMEOUT));
            return Result.success();
        }
    }

    @SysLog(title = "完成订单", businessType = BusinessType.OPERATE)
    @ApiOperation("订单完成")
    @RequiresPermissions(value = {UserType.SPD, UserType.NURSE})
    @PutMapping("/receipt")
    public Result receipt(@Validated @RequestBody OrderReceiptForm orderReceipt) {
        OrderEntity order = orderService.getById(orderReceipt.getOrderId());
        order.setStatus(3);
        order.setSignUserId(getUserId());
        order.setSignUserName(getNickName());
        order.setDoneTime(System.currentTimeMillis());
        // 更新标签取用信息和订单绑定
        if (orderReceipt.getBarcodeList() != null && orderReceipt.getBarcodeList().size() > 0) {
            for (String code : orderReceipt.getBarcodeList()) {
                BarcodeEntity barcode = barcodeService.queryInfoByCode(code);
                if (barcode != null) {
                    barcode.setOrderId(orderReceipt.getOrderId());
                    barcode.setOutboundTime(System.currentTimeMillis());
                    barcode.setOutboundUserId(getUserId());
                    barcode.setOutboundAddressId(order.getDeliveryAddressId());
                    barcode.setStatus(2);
                    barcodeService.updateById(barcode);
                }
            }
        } else {
            logger.warn("订单{}签收时没有标签条码信息", order.getOrderNumber());
        }
        orderService.updateOrder(order);
        // 创建即时消息
        noticeService.createOrderNotice(order, OrderStatus.DONE);
        // 移除配送超时提醒
        redisDelayQueueManager.removeTask(OrderTimeoutDoneTask.TAG + order.getId());
        return Result.success();
    }

    @SysLog(title = "取消订单", businessType = BusinessType.OPERATE)
    @ApiOperation("订单取消")
    @RequiresPermissions(value = {UserType.SPD, UserType.NURSE})
    @PutMapping("/cancel/{orderId}")
    public Result cancel(@PathVariable("orderId") long orderId) {
        OrderEntity order = orderService.getById(orderId);
        if (order.getStatus() == OrderStatus.SHIPPED.getValue()) {
            return Result.error("订单已经在路上了");
        }
        order.setStatus(4);
        orderService.updateOrder(order);
        // 创建即时消息
        noticeService.createOrderNotice(order, OrderStatus.CANCEL);
        // 移除所有超时提醒
        redisDelayQueueManager.removeTask(OrderTimeoutDoneTask.TAG + order.getId());
        return Result.success();
    }

    @SysLog(title = "删除订单", businessType = BusinessType.DELETE)
    @ApiOperation("删除订单信息")
    @RequiresPermissions()
    @DeleteMapping("/delete/{orderId}")
    public Result delete(@PathVariable("orderId") long orderId) {
        orderService.deleteOrder(orderId);
        // 移除所有超时提醒
        redisDelayQueueManager.removeTask(OrderTimeoutDoneTask.TAG + orderId);
        return Result.success();
    }
}
